package capstone.android.application.nalg.data;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

import android.content.Context;
import android.provider.Settings;
import android.util.Log;
import capstone.android.application.nalg.model.Event;
import capstone.android.application.nalg.model.Profile;
import capstone.android.application.nalg.model.Task;

import com.google.gson.Gson;

public class GsonHandler {

	private Gson gson = new Gson();
	private Context context = null;
	
//	public GsonHandler(){}
	
	public GsonHandler(Context context){
		this.context = context;
	}
	public Event updateEvent(Event e)
	{
		Profile curUser = loadProfile();
		ArrayList<Event> eventList = curUser.getEvents();
		for (int i = 0; i < eventList.size(); i++)
			if (eventList.get(i).getId() == e.getId())
				eventList.remove(i);
		eventList.add(e);
		curUser.setEvents(eventList);
		saveProfile(curUser);
		return e;
	}
	public Event addEvent(Event e) 
	{
		Profile curUser = loadProfile();
		ArrayList<Event> eventList = curUser.getEvents();
		if (eventList == null)
			eventList = new ArrayList<Event>();
		eventList.add(e);
		curUser.setEvents(eventList);
		saveProfile(curUser);
		
		return e;
	}
	public ArrayList<Event> removeEvent(int eventId)
	{
		Profile curUser = loadProfile();
		ArrayList<Event> eventList = curUser.getEvents();
		if (eventList == null)
			eventList = new ArrayList<Event>();
		for (Event e : eventList)
			if (e.getId() == eventId)
				eventList.remove(e);
		curUser.setEvents(eventList);
		saveProfile(curUser);
		return eventList;
	}

	public Task updateSubtask(Task task, Task parent)
	{
		ArrayList<Task> subtasks = parent.getSubtasks();
		for (int i = 0; i < subtasks.size(); i++)
		{
			if (subtasks.get(i).getId() == task.getId()){
				subtasks.remove(i);
				break;
			}
		}
		subtasks.add(task);
		parent.setSubtasks(subtasks);
		return parent;
	}
	public int getNextTaskId(int eventId, int curId){
		int nextId = 0;
		String temp = eventId + "" + curId;
		nextId = Integer.parseInt(temp);
		return nextId;
	}
	public Task addSubtask(Task task, Task parent, int eventId)
	{
		ArrayList<Task> subtasks = parent.getSubtasks();
		if (subtasks == null)
			subtasks = new ArrayList<Task>();
		int tempId = -1;
		for (int i = 0; i < subtasks.size(); i++)
		{
			if (subtasks.get(i).getId() == task.getId())
			{
				tempId = subtasks.get(i).getId();
				subtasks.remove(i);
				break;
			}
		}
		
		subtasks.add(task);
		parent.setSubtasks(subtasks);
		Task superParent = null;
		try{
			superParent = getParent(parent, eventId);
		} catch(Exception ex){
			
		}
		if (superParent != null)
			parent = addSubtask(parent, superParent, eventId);
		return parent;
	}
	public Event addTaskToEvent(Task task, Event event){
		ArrayList<Task> tasks = event.getTasks();
		if (tasks == null)
			tasks = new ArrayList<Task>();
		for (Task t : tasks)
		{
			if (t.getId() == task.getId()){
				tasks.remove(t);
				break;
			}
		}
		tasks.add(task);
		event.setTasks(tasks);
		updateEvent(event);
		return event;
	}
	public Event getEvent(int currentEventId) {
		// TODO Auto-generated method stub
		Event fetchedEvent = null;
		Profile curUser = loadProfile();
		ArrayList<Event> events = curUser.getEvents();
		for (Event e : events){
			if (e.getId() == currentEventId){
				fetchedEvent = e;
			}
		}
		return fetchedEvent;
	}
	public ArrayList<Task> removeTask(int taskId, int currentEventId)
	{
		ArrayList<Task> fetchedTasks = null;
		Profile curUser = loadProfile();
		for (Event e : curUser.getEvents())
		{
			if (e.getId() == currentEventId)
			{
				fetchedTasks = removeChild(e.getTasks(), taskId);
				e.setTasks(fetchedTasks);
			}
		}
		return fetchedTasks;
	}
	public Task getParent(Task child, int eventId){
		Task parent = null;
		Event event = getEvent(eventId);
		for(Task t : event.getTasks()){
			if (t.getId() == child.getId())
				return parent;
		}
		for (Task t : event.getTasks()){
			parent = checkParent(child, t);
			if (parent != null)
				break;
		}
		return parent;
	}
	private Task checkParent(Task child, Task parent){
		ArrayList<Task> subtasks = parent.getSubtasks();
		for (Task t : subtasks)
		{
			if (t.getId() == child.getId())
			{
				return parent;
			}
		}
		for (Task t : subtasks)
		{
			parent = checkParent(child, t);
			if (parent != null)
				break;
		}
		return parent;
	}
	public Task getTask(int currentTaskId, int currentEventId) {
		Task fetchedTask = null;
		Profile curUser = loadProfile();
		for (Event e : curUser.getEvents())
		{
			if (e.getId() == currentEventId)
			{
				fetchedTask = getChild(e.getTasks(), currentTaskId);
				break;
			}
		}
		return fetchedTask;
	}
	private Task getChild(ArrayList<Task> taskList, int childId)
	{
		Task child = null;
		boolean foundChild = false;
		for (Task t : taskList)
			if (t.getId() == childId){
				child = t;
				foundChild = true;
			}
		if (!foundChild)
			for (Task t : taskList)
				if ((child = getChild(t.getSubtasks(), childId)) != null)
					break;
		return child;
	}
	private ArrayList<Task> removeChild(ArrayList<Task> taskList, int childId)
	{
		boolean foundChild = false;
		for (Task t : taskList)
			if (t.getId() == childId)
			{
				taskList.remove(t);
				foundChild = true;
				break;
			}
		if (!foundChild)
			for (Task t : taskList)
			{
				if (t.getSubtasks() != null)
				{
					t.setSubtasks(removeChild(t.getSubtasks(), childId));
					break;
				}
			}
		return taskList;
	}
	
	public Profile loadProfile(String ... androidIds){
		Profile p = null;
		String filename = "profile.txt";
		String serialized = null;
		FileInputStream fileInStream;
		try {
			fileInStream = context.openFileInput(filename);
			ObjectInputStream inStream = new ObjectInputStream(fileInStream);
			serialized = (String)inStream.readObject();
			inStream.close();
			p = gson.fromJson(serialized, Profile.class);;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
//			return p;
		}
		if (p == null){
			p = new Profile(androidIds[0]);
			p.setEvents(new ArrayList<Event>());
			saveProfile(p);
		}
		return p;
	}
	public void saveProfile(Profile p) {
		FileOutputStream fileOutStream;
		String filename = "profile.txt";
		String serialized = gson.toJson(p, Profile.class);
		try {
			fileOutStream = context.openFileOutput(filename, Context.MODE_PRIVATE);
			ObjectOutputStream outStream = new ObjectOutputStream(fileOutStream);
			outStream.writeObject(serialized);
			outStream.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
//		ConnectionManager.
		
	}
	
}
